package com.sec.android.app.myfiles.dialog;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.AsyncTask;
import android.text.TextUtils;
import android.widget.Button;
import android.widget.SimpleAdapter;

import com.sec.android.app.myfiles.R;
import com.sec.android.app.myfiles.feature.DlpMgr;
import com.sec.android.app.myfiles.listener.DialogReceiver;
import com.sec.android.app.myfiles.listener.ListenerMgr;
import com.sec.android.app.myfiles.listener.SystemBroadcastReceiver;
import com.sec.android.app.myfiles.listener.SystemBroadcastReceiver.OnMediaUnmounted;
import com.sec.android.app.myfiles.log.Log;
import com.sec.android.app.myfiles.log.SamsungAnalyticsLog;
import com.sec.android.app.myfiles.module.abstraction.FileRecord;
import com.sec.android.app.myfiles.module.abstraction.FileRecord.StorageType;
import com.sec.android.app.myfiles.module.download.DownloadFileRecord;
import com.sec.android.app.myfiles.module.download.DownloadFileRecord.DownloadType;
import com.sec.android.app.myfiles.module.local.recent.RecentFileRecord;
import com.sec.android.app.myfiles.util.DrmUtils;
import com.sec.android.app.myfiles.util.FileDetailUtils;
import com.sec.android.app.myfiles.util.FileDetailUtils.DirInfo;
import com.sec.android.app.myfiles.util.StorageMonitor;
import com.sec.android.app.myfiles.util.UiUtils;

import java.util.ArrayList;
import java.util.HashMap;

public class DetailsDialogFragment extends AbsDialogFragment implements OnMediaUnmounted {
    private static final String TAG = DetailsDialogFragment.class.getSimpleName();
    private Context mContext;

    private ArrayList<FileRecord> mRecordList;
    protected ListenerMgr mListenerMgr;
    private SimpleAdapter mAdapter;

    private static final String DETAIL_NAME = "detail_name";
    private static final String DETAIL_INFO = "detail_info";

    private String mPath;
    private boolean mFromSearch;

    AlertDialog mDetailDialog;

    public DetailsDialogFragment() {
    }

    public static DetailsDialogFragment getInstance(ArrayList<FileRecord> recordList, boolean fromSearch) {
        DetailsDialogFragment fg = new DetailsDialogFragment();
        fg.setRecordList(recordList, fromSearch);
        return fg;
    }

    private void setRecordList(ArrayList<FileRecord> recordList, boolean fromSearch) {
        mRecordList = recordList;
        mFromSearch = fromSearch;
        if (mRecordList != null && !mRecordList.isEmpty() && mRecordList.get(0) != null) {
            mPath = mRecordList.get(0).getFullPath();
        }
    }

    @Override
    protected Dialog _createDialog() {
        Activity a = getActivity();
        mContext = a.getBaseContext();
        mListenerMgr = new ListenerMgr();
        mListenerMgr.addListener(new DialogReceiver(mContext, this, ListenerMgr.LifeCycle.CREATE, ListenerMgr.LifeCycle.DESTROY));
        mListenerMgr.addListener(new SystemBroadcastReceiver(mContext, this, ListenerMgr.LifeCycle.CREATE, ListenerMgr.LifeCycle.DESTROY));
        mListenerMgr.notifyCreate();

        mAdapter = new SimpleAdapter(mContext, getDetailInfoArray(), R.layout.details_dialog_item, new String[]{
                DETAIL_NAME, DETAIL_INFO}, new int[]{
                R.id.details_item_name, R.id.details_item_info});

        mDetailDialog = new AlertDialog.Builder(a).setTitle(getString(R.string.menu_details)).setAdapter(mAdapter, null)
                .setPositiveButton(R.string.ok, new OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dismissAllowingStateLoss();
                        SamsungAnalyticsLog.sendLog(SamsungAnalyticsLog.ScreenPath.DETAILS_POPUP, SamsungAnalyticsLog.Event.OK, null);
                    }
                }).create();

        mDetailDialog.getListView().setFocusable(false);
        return mDetailDialog;
    }

    private ArrayList<HashMap<String, String>> getDetailInfoArray() {
        ArrayList<HashMap<String, String>> details = new ArrayList<>();

        getRecordInfo(details, mRecordList);

        return details;
    }

    private HashMap<String, String> addItem(ArrayList<HashMap<String, String>> list, String detailName, String detailInfo) {
        HashMap<String, String> tempItem = new HashMap<>();
        tempItem.put(DETAIL_NAME, detailName);
        tempItem.put(DETAIL_INFO, detailInfo);
        list.add(tempItem);
        return tempItem;
    }

    private void getRecordInfo(ArrayList<HashMap<String, String>> hash, FileRecord record) {
        if (record.isDirectory()) {
            handleDirectoryRecord(hash, record);
        } else {
            handleFileRecord(hash, record);
        }
    }

    private void handleDirectoryRecord(ArrayList<HashMap<String, String>> hash, FileRecord record) {
        DirInfo dirInfo = new DirInfo();
        FileDetailUtils.getDirInfo(mContext, record, dirInfo, true);
        if (UiUtils.isInRTLMode(mContext)) {
            addItem(hash, getString(R.string.name), "\u200F" + StorageMonitor.getStorageDisplayName(mContext, record.getFullPath()));
        } else {
            addItem(hash, getString(R.string.name), "\u200E" + StorageMonitor.getStorageDisplayName(mContext, record.getFullPath()));
        }

        if (!(mFromSearch && record.getStorageType() == StorageType.Cloud)) {
            addItem(hash, getString(R.string.size), getFileSizeString(dirInfo.size));
        }
        addItem(hash, getString(R.string.last_modified_time), UiUtils.makeTimeString(mContext, record.getDate()));
        addItem(hash, getString(R.string.contains), UiUtils.makeContainsString(mContext, dirInfo.fileCnt, dirInfo.dirCnt));
        addItem(hash, getString(R.string.path), StorageMonitor.convertPathToDisplayedPath(mContext, FileRecord.getPath(record.getFullPath())));
    }

    private void handleFileRecord(ArrayList<HashMap<String, String>> hash, FileRecord record) {
        if (UiUtils.isInRTLMode(mContext)) {
            addItem(hash, getString(R.string.name), "\u200F" + record.getName());
        } else {
            addItem(hash, getString(R.string.name), "\u200E" + record.getName());
        }

        addItem(hash, getString(R.string.size), getFileSizeString(record.getSize()));
        addItem(hash, getString(R.string.last_modified_time), UiUtils.makeTimeString(mContext, record.getDate()));

        if (DrmUtils.isOMADrmFile(mContext, record.getFullPath())) {
            String rightStatus = getResources().getString(R.string.right_status);
            if (!DrmUtils.isForwardable(mContext, record.getFullPath())) {
                addItem(hash, rightStatus, getString(R.string.right_forward_lock));
            }
        }

            /* add except case of display path PLM P151015-04415
            *  receive .vcf file from BT, it does not save as .vcf file but save directly in Contact
            *  so, there is no vcf file if user get from Bluetooth
            */
        if (!(record instanceof DownloadFileRecord && record.getStorageType() == StorageType.Downloads && record.getExt()
                .equalsIgnoreCase("vcf"))) {
            addItem(hash, getString(R.string.path), StorageMonitor.convertPathToDisplayedPath(mContext, record.getPath()));
        }

        String expiryTime = DlpMgr.getInstance(mContext).getExpiryTimeInfo(record);
        if (expiryTime != null) {
            addItem(hash, getString(R.string.dlp_expiry_time), expiryTime);
        }

        // forDownloadHistory
        if ((record instanceof DownloadFileRecord && record.getStorageType() == StorageType.Downloads)
                || (record instanceof RecentFileRecord && ((RecentFileRecord) record).getDownloadType() != DownloadType.DOWNLOAD_BY_NONE)) {
            String description = ((DownloadFileRecord) record).getDescription();

            if (description != null && !description.isEmpty()) {
                if (((DownloadFileRecord) record).getDownloadType() == DownloadType.DOWNLOAD_BY_BROWSER && !((DownloadFileRecord) record).isDownloadedByEmail()) {
                    addItem(hash, getString(R.string.url), description);
                } else {
                    addItem(hash, getString(R.string.sent_from), description);
                }
            } else
                Log.d(this, " download history description is empty so don't display it");
        }
    }

    private void getRecordInfo(ArrayList<HashMap<String, String>> hash, ArrayList<FileRecord> recordList) {
        if (recordList != null && !recordList.isEmpty()) {
            if (recordList.size() == 1 && recordList.get(0) != null) {
                getRecordInfo(hash, recordList.get(0));
            } else {
                RecordsInfoTaskItem taskItem = new RecordsInfoTaskItem();
                taskItem.mRecordList = recordList;
                taskItem.mTotalSizeInfo = addItem(hash, getString(R.string.total_size), getString(R.string.processing));
                taskItem.mContainsInfo = addItem(hash, getString(R.string.contains), getString(R.string.processing));
                mRecordsInfoTask.execute(taskItem);
            }
        }
    }

    @Override
    public void onMediaUnmounted(String path) {
        Log.d(this, "onMediaUnmounted - " + path);
        if (TextUtils.isEmpty(path) || TextUtils.isEmpty(mPath)) {
            return;
        }

        if (mPath.startsWith(path)) {
            dismissAllowingStateLoss();
        }
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        super.onDismiss(dialog);
        mListenerMgr.notifyDestroy();
        if (mRecordList != null) {
            mRecordList.clear();
            mRecordList = null;
        }
        if (mRecordsInfoTask.getStatus() != AsyncTask.Status.FINISHED) {
            mRecordsInfoTask.cancel(true);
        }
    }

    private String getFileSizeString(long size) {
        String ret = UiUtils.makeFileSizeString(mContext, size);
        android.util.Log.d(TAG, ret + " (" + size + ')');
        return ret;
    }

    private AsyncTask<RecordsInfoTaskItem, Void, Void> mRecordsInfoTask = new AsyncTask<RecordsInfoTaskItem, Void, Void>() {
        @Override
        protected Void doInBackground(RecordsInfoTaskItem... params) {
            RecordsInfoTaskItem taskItem = params[0];
            ArrayList<FileRecord> recordList = taskItem.mRecordList;
            DirInfo dirInfo = new DirInfo();

            for (FileRecord record : recordList) {
                if (record != null) {
                    if (record.isDirectory()) {
                        dirInfo.dirCnt++; // getDirInfo do not add it self.
                        FileDetailUtils.getDirInfo(mContext, record, dirInfo, true);
                    } else {
                        dirInfo.fileCnt++;
                        dirInfo.size += record.getSize();
                    }
                }
            }
            if (!isCancelled()) {
                taskItem.mTotalSizeInfo.put(DETAIL_INFO, getFileSizeString(dirInfo.size));
                taskItem.mContainsInfo.put(DETAIL_INFO, UiUtils.makeContainsString(mContext, dirInfo.fileCnt, dirInfo.dirCnt));
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            if (!isCancelled()) {
                mAdapter.notifyDataSetChanged();
            }
        }
    };

    private static class RecordsInfoTaskItem {
        public ArrayList<FileRecord> mRecordList;
        public HashMap<String, String> mTotalSizeInfo;
        public HashMap<String, String> mContainsInfo;
    }

    public void showAllowingStateLoss(final FragmentManager fm, final String tag) {
        if (fm != null) {
            final FragmentTransaction t = fm.beginTransaction();
            t.add(this, tag);
            t.commitAllowingStateLoss();
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        if (mDetailDialog != null) {
            Button positiveBtn = mDetailDialog.getButton(DialogInterface.BUTTON_POSITIVE);
            if (positiveBtn != null) {
                positiveBtn.requestFocus();
            }
        }
    }
}
